package com.rankeiot.platform.controller;


import cn.hutool.core.date.LocalDateTimeUtil;
import com.rankeiot.core.anno.Auth;
import com.rankeiot.core.data.response.PageResp;
import com.rankeiot.core.data.response.Resp;
import com.rankeiot.core.job.JobManager;
import com.rankeiot.core.job.JobMeta;
import com.rankeiot.core.inner.argumet.QueryPage;
import com.rankeiot.core.sqltoy.Sql;
import com.rankeiot.platform.PlatformMenu;
import com.rankeiot.platform.domain.JobInfo;
import com.rankeiot.platform.domain.JobLog;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.sagacity.sqltoy.dao.SqlToyLazyDao;
import org.sagacity.sqltoy.model.Page;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.support.CronExpression;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;

/**
 * 定时任务
 *
 * @author desire
 */
@Auth(PlatformMenu.JOBS)
@RestController
@RequestMapping("jobs")
@RequiredArgsConstructor
public class JobsController {
    final SqlToyLazyDao dao;
    final TaskScheduler scheduler;
    @PostMapping(path="list")
    public PageResp<JobInfo> list(QueryPage query) {

        Sql sql = Sql.select("*")
                .from(JobInfo.class)
                .filter()
                .like(JobInfo.Fields.id)
                .orderByDesc(JobInfo.Fields.id);
        Page<JobInfo> ret = dao.findPageBySql(query.page(), sql.toString(), query.getParams(), JobInfo.class);

//        for (JobInfo info : ret.getRows()) {
////            CronPattern cp = new CronPattern(info.getCron());
////            Calendar nc = cp.nextMatchAfter(now);
////            info.setNextTime(nc.getTime());
//            CronExpression exp= CronExpression.parse(info.getCron());
//            LocalDateTime next = exp.next(LocalDateTimeUtil.now());
//            info.setNextTime(Date.from(next.atZone(ZoneId.systemDefault()).toInstant()));
//           // CronSequenceGenerator cronSequenceGenerator = new CronSequenceGenerator(cron);
//        }
        return Resp.of(ret);
    }

    @PostMapping(path="list_log")
    public PageResp<JobLog> listLog(QueryPage query) {
        Sql sql = Sql.select("*")
                .from(JobLog.class)
                .eq(JobLog.Fields.taskId)
                .orderByDesc(JobLog.Fields.id);
        return Resp.of(dao.findPageBySql(query.page(), sql.toString(), query.getParams(), JobLog.class));
    }

    @PostMapping(path="enable")
    public Resp enable(@RequestBody JobVo job){
        JobInfo jb=new JobInfo();
        jb.setId(job.id);
        jb.setEnable(job.enable);
        if(job.enable){
           JobManager.schedule(job.id);
        }else{
            JobManager.cancelSchedule(job.id);
        }
        dao.update(jb);
        return Resp.ok();
    }
    @PostMapping("save")
    public Resp save(@RequestBody JobInfo job){
        //验证corn
        try{
            CronExpression.parse(job.getCron()) ;
        }catch (Exception e){
            Resp.fail("时间表达式错误："+e.getMessage());
        }

        JobInfo old=new JobInfo();
        old.setId(job.getId());
        old=dao.load(old);
        if(old!=null){
            if(!old.getCron().equals(job.getCron())){
                old.setCron(job.getCron());
                JobMeta jm= JobManager.getJob(job.getId());
                if(jm!=null){
                    old.setNextTime(jm.nextTime());
                    jm.setCron(job.getCron());
                    jm.cancelSchedule();
                    JobManager.schedule(job.getId());
                }
            }
            old.setDescribe(job.getDescribe());
            old.setTitle(job.getTitle());
            dao.update(old);
        }
        return Resp.ok();
    }
    @PostMapping(path="run")
    public Resp run(@RequestBody JobVo job){
        JobMeta jm= JobManager.getJob(job.id);
        if(jm==null){
            Resp.fail("任务不存在");
        }
        jm.runJob(true);
        return Resp.ok();
    }
    @Data
    public static class JobVo{
        String id;
        Boolean enable;
    }
}
